package org.gruposp2p.proyectokarma.gwt.client.ui;

import java.util.HashSet;
import java.util.Set;
import org.gruposp2p.proyectokarma.gwt.client.MainEntryPoint;
import org.gruposp2p.proyectokarma.gwt.client.domain.Tag;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import org.gruposp2p.proyectokarma.gwt.client.widget.ClickableLabel;

public class AddTagsDialog implements ClickableLabel.Handler {
	
	int maxFrequency = 0;
	int minFrequency = 600000000;
	final int MIN_FONT_SIZE = 8;
	final int MAX_FONT_SIZE = 25;
    
    @UiField DialogBox dialogBox;
    @UiField VerticalPanel mainPanel;
    @UiField VerticalPanel inputPanelsContainer;
    @UiField FlowPanel selectedTagsPanel;
    @UiField Button acceptButton;
    @UiField Button cancelButton;
    @UiField Button tagsButton;
    @UiField TextBox tagsTextBox;
    @UiField Anchor mostCommonTagsAnchor;
    @UiField FlowPanel mostCommonTagsPanel;
    
    boolean mostCommonTagsPanelVisibility = false;
    
    Handler dialogHandler;
    
    Set<String> tagSet;

    private static AddTagsDialogUiBinder uiBinder = GWT
                    .create(AddTagsDialogUiBinder.class);

    interface AddTagsDialogUiBinder extends
            UiBinder<Widget, AddTagsDialog> {
    }

    public AddTagsDialog() {
        uiBinder.createAndBindUi(this);
        SubmitHandler sh = new SubmitHandler();
        mostCommonTagsPanel.setVisible(mostCommonTagsPanelVisibility);
        mostCommonTagsAnchor.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				mostCommonTagsPanelVisibility = !mostCommonTagsPanelVisibility;
				mostCommonTagsPanel.setVisible(mostCommonTagsPanelVisibility);
			}
		});
        selectedTagsPanel.setStylePrimaryName("cloudWrap");
        mostCommonTagsPanel.setStylePrimaryName("cloudWrap");
        acceptButton.setStylePrimaryName("acceptButton");
        acceptButton.setVisible(false);
        cancelButton.setStylePrimaryName("cancelButton");
        tagsButton.setStylePrimaryName("addButton");
        tagsButton.setStylePrimaryName("addTagButton");
        tagsTextBox.addKeyDownHandler(sh);
        loadMostCommonTags(MainEntryPoint.INSTANCE.sessionData.getTags());
    }

    public void show(Handler handler) {
    	this.dialogHandler = handler;
    	tagSet = new HashSet<String>();
    	selectedTagsPanel.clear();
        dialogBox.setPopupPosition((Window.getClientWidth()/4), 40);
        acceptButton.setVisible(false);
        //dialogBox.center();
        dialogBox.show();
    }
   
    @UiHandler("acceptButton")
    void handleAcceptButton(ClickEvent e) {
    	dialogHandler.updateTagsPanel(tagSet);
		dialogBox.hide();
    }
    
    @UiHandler("tagsButton")
    void handleTagsButton(ClickEvent e) {
    	if ("".equals(tagsTextBox.getText().trim())) return;
    	String[] tags = tagsTextBox.getText().toLowerCase().split(",");
    	for (String tag : tags) {
    		tag = tag.replaceAll("[,.?!/,'\"]+", "");
    		if (!tagSet.contains(tag)) tagSet.add(tag);	
    	}
    	tagsTextBox.setText("");
    	showSelectedTags();
    }
    
	private void showSelectedTags () {
    	selectedTagsPanel.clear();
    	for (String tag : tagSet) {
    		ClickableLabel tagLabel = new ClickableLabel(
    				tag, this, ClickableLabel.Type.TAG);
    		selectedTagsPanel.add(tagLabel);
    	}
        acceptButton.setVisible(tagSet.size() > 0);
	}
    
    @UiHandler("cancelButton")
    void handleCancelButton(ClickEvent e) {
    	dialogBox.hide();
    }

    
    public void loadMostCommonTags (Set<Tag> tagSet) {
    	AnchorClickHandler clickHandler = 
    		new AnchorClickHandler();
    	for (Tag tag :  tagSet) {
        	Anchor tagLink = new Anchor(tag.getName());
        	tagLink.addClickHandler(clickHandler);
        	tagLink.setStylePrimaryName("clickableLabel"); 
        	mostCommonTagsPanel.add(tagLink); 
        	int frequency = (int)tag.getFrequency();
        	if (minFrequency > frequency)
                minFrequency = frequency;
            if (maxFrequency < frequency)
                maxFrequency = frequency;
            Style linkStyle = (Style) tagLink.getElement().getStyle();
            linkStyle.setProperty("fontSize", getLabelSize(frequency));
    	}
    }
	
    private class AnchorClickHandler implements ClickHandler {
		@Override
		public void onClick(ClickEvent event) {
			String selectedTag = ((Anchor)event.getSource()).getText();
			if (!tagSet.contains(selectedTag)) tagSet.add(selectedTag);	
	    	showSelectedTags();
		}
	}
    
    private class SubmitHandler implements KeyDownHandler {
		@Override
		public void onKeyDown(KeyDownEvent event) {
			if (KeyCodes.KEY_ENTER == event.getNativeKeyCode()) {
				acceptButton.click();
			}		
		}
	}

    public interface Handler {
    	void updateTagsPanel(Set<String> tagSet);
    }
    
    public String getLabelSize(int frequency){
        double weight = (Math.log(frequency) - Math.log(minFrequency)) / (Math.log(maxFrequency) - Math.log(minFrequency));
        int fontSize = MIN_FONT_SIZE + (int)Math.round((MAX_FONT_SIZE - MIN_FONT_SIZE) * weight);
        return Integer.toString(fontSize) + "pt";
    }

	@Override
	public void processIconClick(ClickableLabel tagLabel) {
		tagSet.remove(tagLabel.getText());
		showSelectedTags();	
	}

}